﻿using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace FontTool
{
    public partial class FontToolMain
    {
        #region variables
        string uriDummySets = @"XML\DummySet.xml";
        Dictionary<string, dummySet> DummySets = new Dictionary<string, dummySet>();
        string currentDummySet = "Default";
        bool useDummy = true;
        int dummyNumberOFImages = 0;
        #endregion

        #region comboBoxDummySetsInit \ checkBoxDummy_CheckedChanged
        private void comboBoxDummySetsInit()
        {
            comboBoxDummySets.Items.Clear();
            foreach (var c in DummySets)
                comboBoxDummySets.Items.Add(c.Key);
            comboBoxDummySets.SelectedIndex = comboBoxDummySets.Items.IndexOf("Default");
        }

        private void checkBoxDummy_CheckedChanged(object sender, EventArgs e)
        {
            switch (checkBoxDummy.CheckState)
            {
                case CheckState.Checked:
                    if (newFont != null)
                    {
                        useDummy = true;
                        updateDataGridView();
                    }
                    break;
                case CheckState.Unchecked:
                    if (newFont != null)
                    {
                        useDummy = false;
                        updateDataGridView();
                    }
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region dummyDataGridViewInit \ dummyLoadImagesToGridView
        private void DataGridViewInitDummy()
        {
            dataGridViewGlyphs.Rows.Clear();
            dataGridViewGlyphs.Columns.Clear();

            if (currentFilter != "NONE")
                dummyNumberOFImages = Filters[currentFilter].Count;
            else
            {
                if (DummySets[currentDummySet].Count != 0)
                    dummyNumberOFImages = DummySets[currentDummySet].Count;
                else
                    dummyNumberOFImages = newFont.Characters.Count;
            }

            int columnsPerWidth = (dataGridViewGlyphs.Width - SystemInformation.VerticalScrollBarWidth) / imgWidth;
            int columnWidth = (dataGridViewGlyphs.Size.Width - SystemInformation.VerticalScrollBarWidth) / columnsPerWidth;
            int numberOfRows = 0;

            numberOfRows = dummyNumberOFImages / columnsPerWidth;

            // Do we have a an overfill for a row
            if (dummyNumberOFImages % columnsPerWidth > 0)
            {
                numberOfRows += 1;
            }

            dummyNumberOFImages = numberOfRows * columnsPerWidth;

            // Dynamically create the columns
            for (int index = 0; index < columnsPerWidth; index++)
            {
                customDataGridViewImageColumn dataGridViewColumn = new customDataGridViewImageColumn();
                dataGridViewGlyphs.Columns.Add(dataGridViewColumn);
                dataGridViewGlyphs.Columns[index].Width = columnWidth;
            }

            // Create the rows
            for (int index = 0; index < numberOfRows; index++)
            {
                dataGridViewGlyphs.Rows.Add();
                dataGridViewGlyphs.Rows[index].Height = columnWidth;
            }
        }

        private void LoadImagesToGridViewDummy()
        {
            int columnIndex = 0;
            int rowIndex = 0;
            for (int index = 0; index < DummySets[currentDummySet].Count; index++)
            {
                if (currentFilter == "NONE")
                {
                    Image image = Helper.ResizeImage(Helper.drawImageFromHex(DummySets[currentDummySet].Characters[index]), imgWidth, imgWidth, false);

                    (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).dummyImage = image;
                    dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].Value = (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).dummyImage;
                    //need test
                    (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).cSource = customDataGridViewCell.cellSource.Dummy;
                    dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].ToolTipText = Helper.stringToHex(DummySets[currentDummySet].Characters[index].ToString())[0];

                    if (columnIndex == dataGridViewGlyphs.Columns.Count - 1)
                    {
                        rowIndex += 1;
                        columnIndex = 0;
                    }
                    else
                    {
                        columnIndex++;
                    }
                }

                if (currentFilter != "NONE")
                {
                    if (Filters[currentFilter].Hexs.Contains(Helper.charToHex(DummySets[currentDummySet].Characters[index])))
                    {
                        Image image = Helper.ResizeImage(Helper.drawImageFromHex(DummySets[currentDummySet].Characters[index]), imgWidth, imgWidth, false);

                        (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).dummyImage = image;
                        dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].Value = (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).dummyImage;
                        //need test
                        (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).cSource = customDataGridViewCell.cellSource.Dummy;
                        dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].ToolTipText = Helper.stringToHex(DummySets[currentDummySet].Characters[index].ToString())[0];

                        if (columnIndex == dataGridViewGlyphs.Columns.Count - 1)
                        {
                            rowIndex += 1;
                            columnIndex = 0;
                        }
                        else
                        {
                            columnIndex++;
                        }
                    }
                }
            }

            //takes care of empty cells
            foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                foreach (customDataGridViewCell cell in row.Cells)
                    if (cell.Value == null)
                    {
                        DataGridViewCellStyle dataGridViewCellStyle = new DataGridViewCellStyle();
                        dataGridViewCellStyle.NullValue = null;
                        dataGridViewCellStyle.Tag = "BLANK";
                        cell.Style = dataGridViewCellStyle;
                        cell.cSource = customDataGridViewCell.cellSource.Dummy;
                    }
        }
        #endregion

        #region loadImagesToGridView : LITGVnoDummy \ LITGVDummy
        private void LoadImagesToGridView()
        {
            if (newFont != null)
            {
                if (useDummy)
                {
                    LITGVDummy();
                }
                else
                {
                    LITGVnoDummy();
                }
            }
        }

        private void LITGVnoDummy()
        {
            int columnIndex = 0;
            int rowIndex = 0;
            for (int index = 0; index < newFont._Characters.Count; index++)
            {
                if (currentFilter != "NONE")
                {
                    if (Filters[currentFilter].Hexs.Contains(newFont._Characters[index]._Name))
                    {
                        Image image = Helper.ResizeImage(newFont._Characters[index]._ImageUri, imgWidth, imgWidth, false);

                        (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).xmlImage = image;
                        dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].Value = (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).xmlImage;
                        dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].ToolTipText = newFont._Characters[index]._Name;
                        //need test
                        (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).cSource = customDataGridViewCell.cellSource.XML;

                        if (columnIndex == dataGridViewGlyphs.Columns.Count - 1)
                        {
                            rowIndex += 1;
                            columnIndex = 0;
                        }
                        else
                        {
                            columnIndex++;
                        }
                    }
                }

                if (currentFilter == "NONE")
                {
                    Image image = Helper.ResizeImage(newFont._Characters[index]._ImageUri, imgWidth, imgWidth, false);

                    (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).xmlImage = image;
                    dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].Value = (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).xmlImage;
                    dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex].ToolTipText = newFont._Characters[index]._Name;
                    //need test
                    (dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex] as customDataGridViewCell).cSource = customDataGridViewCell.cellSource.XML;

                    if (columnIndex == dataGridViewGlyphs.Columns.Count - 1)
                    {
                        rowIndex += 1;
                        columnIndex = 0;
                    }
                    else
                    {
                        columnIndex++;
                    }
                }
            }

            foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                foreach (customDataGridViewCell cell in row.Cells)
                    if (cell.Value == null)
                    {
                        DataGridViewCellStyle dataGridViewCellStyle = new DataGridViewCellStyle();
                        dataGridViewCellStyle.NullValue = null;
                        dataGridViewCellStyle.Tag = "BLANK";
                        cell.Style = dataGridViewCellStyle;
                    }
        }

        private void LITGVDummy()
        {
            if (currentFilter == "NONE")
                for (int index = 0; index < newFont._Characters.Count; index++)
                {
                    foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                    {
                        foreach (customDataGridViewCell cell in row.Cells)
                            if (cell.ToolTipText == newFont._Characters[index]._Name)
                            {
                                Image image = Helper.ResizeImage(newFont._Characters[index]._ImageUri, imgWidth, imgWidth, false);
                                cell.xmlImage = image;
                                cell.Value = cell.xmlImage;
                                cell.cSource = customDataGridViewCell.cellSource.XML;
                            }
                    }
                }

            if (currentFilter != "NONE")
            {
                for (int index = 0; index < newFont._Characters.Count; index++)
                    if (Filters[currentFilter].Hexs.Contains(newFont._Characters[index]._Name))
                        foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                            foreach (customDataGridViewCell cell in row.Cells)
                                if (cell.ToolTipText == newFont._Characters[index]._Name)
                                {
                                    Image image = Helper.ResizeImage(newFont._Characters[index]._ImageUri, imgWidth, imgWidth, false);
                                    cell.xmlImage = image;
                                    cell.Value = cell.xmlImage;
                                    cell.cSource = customDataGridViewCell.cellSource.XML;
                                }
            }
        }
        #endregion

        #region gridViewContextMenu_ItemClicked: addCharacter \ replaceCharacter \ removeCharacter \ editCharacter \ openInEditorCharacter
        void gridViewContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "Add...":
                    gridViewContextMenu.Visible = false;
                    addCharacter();
                    break;
                case "Add origin...":
                    gridViewContextMenu.Visible = false;
                    AddOriginCharacter();
                    break;
                case "Replace...":
                    gridViewContextMenu.Visible = false;
                    replaceCharacter();
                    break;
                case "Remove...":
                    gridViewContextMenu.Visible = false;
                    removeCharacter();
                    break;
                case "Edit...":
                    gridViewContextMenu.Visible = false;
                    editCharacter();
                    break;
                case "Open in Editor...":
                    gridViewContextMenu.Visible = false;
                    openInEditorCharacter();
                    break;
                default:
                    gridViewContextMenu.Visible = false;
                    break;
            }
        }

        private void addCharacter()
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Multiselect = true;

                if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    foreach (string s in ofd.FileNames)
                    {
                        if (s.StartsWith("0x"))
                            newFont.addCharacter(s);
                        else
                            MessageBox.Show("The image you are trying to insert is not named as hex value");
                    }
                    refreshList();
                    updateDataGridView();
                    timerUpdatePreview.Start();
                }
            }
        }

        private void replaceCharacter()
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    newFont.replaceCharacter(dataGridViewGlyphs.CurrentCell.ToolTipText, newFont.createCharacter(ofd.FileName));
                    refreshList();
                    updateDataGridView();
                    timerUpdatePreview.Start();
                }
            }
        }

        private void removeCharacter()
        {
            DialogResult ds = MessageBox.Show("Delete all selected character?", "Confirm delete", MessageBoxButtons.YesNoCancel);

            if (ds == System.Windows.Forms.DialogResult.Yes)
            {
                foreach (customDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
                {
                    newFont.deleteCharacter(s.ToolTipText);
                }
                refreshList();
                updateDataGridView();
                timerUpdatePreview.Start();
            }

            if (ds == System.Windows.Forms.DialogResult.No)
            {
                foreach (customDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
                {
                    if (s.cSource == customDataGridViewCell.cellSource.XML)
                        if (MessageBox.Show("Delete character '" + s.ToolTipText + "'", "Confirm delete", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                        {
                            newFont.deleteCharacter(s.ToolTipText);
                        }
                }
                refreshList();
                updateDataGridView();
            }
        }

        private void editCharacter()
        {
            foreach (customDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
            {
                if (s.cSource == customDataGridViewCell.cellSource.XML)
                {
                    Editor gc = new Editor(newFont, newFont.getCharacter(s.ToolTipText));
                    gc.refreshRequest = new Editor.sendRefreshRequest(requestToUpdatePreview);
                    gc.Show();
                }
            }

        }

        private void openInEditorCharacter()
        {
            foreach (customDataGridViewCell s in dataGridViewGlyphs.SelectedCells)
            {
                if (s.cSource == customDataGridViewCell.cellSource.XML)
                {
                    //open character in default editor;
                    
                    //startInfo.FileName = "MSPAINT.EXE";
                    //startInfo.Verb = "openas";
                    //System.Diagnostics.Process.Start(startInfo);
                    Process p = new Process();
                    ProcessStartInfo startInfo = new ProcessStartInfo("rundll32.exe");
                    startInfo.UseShellExecute = false;
                    startInfo.RedirectStandardOutput = true;
                    startInfo.Arguments = "shell32.dll ,OpenAs_RunDLL " + newFont.getCharacter(s.ToolTipText)._ImageUri;
                    p.StartInfo = startInfo;
                    p.Start();
                }
            }
        }

        private void AddOriginCharacter()
        {
            string missingChars = string.Empty;
            DialogResult dr = Helper.InputBox("Add origin character", "Insert character: ", ref missingChars);
            Console.WriteLine(/******************************************************/);
            Console.WriteLine(missingChars);
            Console.WriteLine(newFont.FontOriginName);
            Console.WriteLine(newFont.FontOriginBold);
            Console.WriteLine(newFont.FontOriginItalic);
            Console.WriteLine(newFont.FontOriginSize);
            Console.WriteLine(newFont.FontOriginColor);
            Console.WriteLine(/******************************************************/);
            using (ttf2png t2p = new ttf2png())
            {
                t2p.FontName.Text = newFont.FontOriginName;
                t2p.FontStyle.Text = getFontStyle();
                t2p.FontSize.Text = newFont.FontOriginSize.ToString();
                t2p.Sample.ForeColor = Color.FromArgb(newFont.FontOriginColor);
                t2p.checkBoxNUMBERS.Checked = false;
                t2p.checkBoxUPPERCASE.Checked = false;
                t2p.checkBoxLOWERCASE.Checked = false;
                t2p.checkBoxSPECIAL.Checked = false;
                t2p.checkBoxSYMBOLS.Checked = false;
                t2p.checkBoxpng.Checked = false;
                t2p.textBox1.Text = missingChars;
                t2p.Export_Click(null, null);
            }
        }

        private string getFontStyle()
        {
            string msg = "Regular";
            if (newFont.FontOriginBold)
                msg = "Bold";
            if (newFont.FontOriginItalic)
                msg = "Italic";
            if (newFont.FontOriginBold && newFont.FontOriginItalic)
                msg = "Bold, Italic";
            return msg;
        }
        #endregion

        #region buttonZoomIn_Click \ buttonZoomOut_Click \ buttonGridViewOrigin_Click
        private void buttonZoomIn_Click(object sender, EventArgs e)
        {
            imgWidth += 2;
            updateDataGridView();
        }

        private void buttonZoomOut_Click(object sender, EventArgs e)
        {
            imgWidth -= 2;
            updateDataGridView();
        }

        private void buttonGridViewOrigin_Click(object sender, EventArgs e)
        {
            if (newFont != null)
            {
                imgOrigin = Helper.getDefaultWidth(newFont.Characters);
                imgWidth = imgOrigin;
                updateDataGridView();
            }
        }
        #endregion

        #region comboBoxFilterInit \ comboBoxFilter_SelectedIndexChanged
        private void comboBoxFilterInit()
        {
            comboBoxFilter.Items.Clear();
            foreach (var c in Filters)
                comboBoxFilter.Items.Add(c.Key);
            comboBoxFilter.SelectedIndex = comboBoxFilter.Items.IndexOf("NONE");
        }

        private void comboBoxFilter_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxFilter.SelectedItem != null)
            {
                currentFilter = comboBoxFilter.SelectedItem.ToString();
                updateDataGridView();
            }
        }
        #endregion

        #region textBoxSearch_KeyPress \ dataGridViewGlyphs_KeyDown
        private void textBoxSearch_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                bool contains = false;

                if (textBoxSearch.Text.StartsWith("0x"))
                {
                    if (newFont.containsCharHEX(textBoxSearch.Text))
                        contains = true;
                }

                if (textBoxSearch.Text.Length == 1)
                {
                    if (newFont.containsCharCHARACTER(textBoxSearch.Text[0]))
                    {
                        contains = true;
                        textBoxSearch.Text = Helper.charToHex(textBoxSearch.Text[0]);
                    }
                }

                if (contains)
                {
                    foreach (DataGridViewRow row in dataGridViewGlyphs.Rows)
                        foreach (customDataGridViewCell cell in row.Cells)
                            if (cell.ToolTipText == textBoxSearch.Text)
                                dataGridViewGlyphs.CurrentCell = cell;
                }
            }
        }
        
        private void dataGridViewGlyphs_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                editCharacter();
            }
            if (e.KeyData == Keys.Delete)
            {
                removeCharacter();
            }
        }
        #endregion

        #region dataGridViewGlyphs_DragDrop \ dataGridViewGlyphs_DragEnter
        private void dataGridViewGlyphs_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FileDrop"))
            {

                string[] files = (e.Data.GetData("FileDrop") as string[]);

                if (files.Length == 1 && Path.GetExtension(files[0]) == ".xml")
                {
                    loadFontXML(files[0]);
                    InitViews();
                    timerUpdatePreview.Start();
                }

                else
                {
                    foreach (string s in files)
                    {
                        if (System.IO.Path.GetExtension(s) == ".png")
                        {
                            newFont.addCharacter(s);
                        }
                    }
                }
            }
            refreshList();
            updateDataGridView();
            timerUpdatePreview.Start();
        }

        private void dataGridViewGlyphs_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }
        #endregion

        #region dataGridViewGlyphs_MouseDown \ dataGridViewGlyphs_MouseDoubleClick
        private void dataGridViewGlyphs_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (!cellSourceDummy())
                editCharacter();
        }
        
        private void dataGridViewGlyphs_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                if (dataGridViewGlyphs.SelectedCells.Count <= 1)
                {
                    int rowIndex = this.dataGridViewGlyphs.HitTest(e.X, e.Y).RowIndex;
                    int columnIndex = this.dataGridViewGlyphs.HitTest(e.X, e.Y).ColumnIndex;
                    dataGridViewGlyphs.CurrentCell = this.dataGridViewGlyphs.Rows[rowIndex].Cells[columnIndex];
                }
            }
        }
        #endregion

        private void zoomContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "25%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (25 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "25%";
                    break;
                case "50%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (50 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "50%";
                    break;
                case "75%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (75 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "75%";
                    break;
                case "100%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (100 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "100%";
                    break;
                case "125%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (125 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "125%";
                    break;
                case "150%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (150 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "150%";
                    break;
                case "175%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (175 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "175%";
                    break;
                case "200%":
                    zoomContextMenu.Visible = false;
                    imgWidth = (200 * imgOrigin) / 100;
                    updateDataGridView();
                    labelGridScale.Text = "200%";
                    break;
                default:
                    break;
            }
        }

        private bool cellSourceDummy()
        {
            if ((dataGridViewGlyphs.CurrentCell as customDataGridViewCell).cSource == customDataGridViewCell.cellSource.Dummy)
                return true;
            else
                return false;
        }

        private void updateDataGridView()
        {

            if (imgWidth == 0)
            {
                imgWidth = 30;
                imgOrigin = 30;
            }

            DataGridViewInitDummy();

            if (useDummy)
            {
                LoadImagesToGridViewDummy();
            }

            if (newFont != null)
            {
                LoadImagesToGridView();
                refreshList();
            }

            labelGridScale.Text = Helper.getScale(imgOrigin, imgWidth).ToString() + "%";
        }
    }
}
